package controllers

import (
	"net/http"
	"strconv"

	"gitee.com/kun_liu/to-log/app/models"
	"gitee.com/kun_liu/to-log/app/services"
	"gitee.com/kun_liu/to-log/pkg/database"
	"github.com/gin-contrib/sessions"
	"github.com/gin-gonic/gin"
)

// AdminController 后台控制器
type AdminController struct {
	postService     *services.PostService
	pageService     *services.PageService
	categoryService *services.CategoryService
	tagService      *services.TagService
	commentService  *services.CommentService
	userService     *services.UserService
	optionService   *services.OptionService
}

// NewAdminController 创建后台控制器实例
func NewAdminController() *AdminController {
	return &AdminController{
		postService:     services.NewPostService(),
		pageService:     services.NewPageService(),
		categoryService: services.NewCategoryService(),
		tagService:      services.NewTagService(),
		commentService:  services.NewCommentService(),
		userService:     services.NewUserService(),
		optionService:   services.NewOptionService(),
	}
}

// Logout 退出登录
func (c *AdminController) Logout(ctx *gin.Context) {
	// 清除会话
	session := sessions.Default(ctx)
	session.Clear()
	session.Save()

	// 重定向到登录页面
	ctx.Redirect(http.StatusFound, "/admin/login")
}

// Dashboard 后台首页
func (c *AdminController) Dashboard(ctx *gin.Context) {
	session := sessions.Default(ctx)
	username := session.Get("username")

	ctx.HTML(http.StatusOK, "admin-dashboard.html", gin.H{
		"title":    "后台首页",
		"username": username,
	})
}

// Login 登录页面
func (c *AdminController) Login(ctx *gin.Context) {
	session := sessions.Default(ctx)

	// 如果用户已登录，重定向到后台首页
	if session.Get("user_id") != nil {
		ctx.Redirect(http.StatusFound, "/admin")
		return
	}

	// 如果是POST请求，处理登录逻辑
	if ctx.Request.Method == "POST" {
		username := ctx.PostForm("username")
		password := ctx.PostForm("password")

		// 验证用户名和密码
		user, err := c.userService.Login(username, password)
		if err != nil {
			ctx.HTML(http.StatusOK, "admin-login.html", gin.H{
				"title": "登录",
				"error": "用户名或密码错误",
			})
			return
		}

		// 设置会话
		session.Set("user_id", user.ID)
		session.Set("username", user.Name)
		session.Save()

		// 重定向到后台首页
		ctx.Redirect(http.StatusFound, "/admin")
		return
	}

	// GET请求，显示登录页面
	ctx.HTML(http.StatusOK, "admin-login.html", gin.H{
		"title": "登录",
	})
}

// Register 注册页面
func (c *AdminController) Register(ctx *gin.Context) {
	session := sessions.Default(ctx)

	// 如果用户已登录，重定向到后台首页
	if session.Get("user_id") != nil {
		ctx.Redirect(http.StatusFound, "/admin")
		return
	}

	// 如果是POST请求，处理注册逻辑
	if ctx.Request.Method == "POST" {
		username := ctx.PostForm("username")
		email := ctx.PostForm("email")
		password := ctx.PostForm("password")
		confirmPassword := ctx.PostForm("confirm_password")

		// 验证密码是否匹配
		if password != confirmPassword {
			ctx.HTML(http.StatusOK, "admin-register.html", gin.H{
				"title": "注册",
				"error": "两次输入的密码不一致",
			})
			return
		}

		// 创建用户
		user := &models.User{
			Name:     username,
			Mail:     email,
			Password: password,
			Group:    "administrator", // 设置为管理员组
		}

		// 保存用户
		err := c.userService.CreateUser(user)
		if err != nil {
			ctx.HTML(http.StatusOK, "admin-register.html", gin.H{
				"title": "注册",
				"error": "注册失败：" + err.Error(),
			})
			return
		}

		// 设置会话
		session.Set("user_id", user.ID)
		session.Set("username", user.Name)
		session.Save()

		// 重定向到后台首页
		ctx.Redirect(http.StatusFound, "/admin")
		return
	}

	// GET请求，显示注册页面
	ctx.HTML(http.StatusOK, "admin-register.html", gin.H{
		"title": "注册",
	})
}

// PostList 文章列表
func (c *AdminController) PostList(ctx *gin.Context) {
	// 获取分页参数
	page, _ := strconv.Atoi(ctx.DefaultQuery("page", "1"))
	pageSize, _ := strconv.Atoi(ctx.DefaultQuery("page_size", "10"))

	// 获取文章列表
	posts, total, err := c.postService.GetPosts(page, pageSize)
	if err != nil {
		ctx.HTML(http.StatusInternalServerError, "error.html", gin.H{
			"title": "服务器错误",
			"error": err.Error(),
		})
		return
	}

	ctx.HTML(http.StatusOK, "admin-post-list.html", gin.H{
		"title":      "文章管理",
		"posts":      posts,
		"total":      total,
		"page":       page,
		"pageSize":   pageSize,
		"totalPages": (total + int64(pageSize) - 1) / int64(pageSize),
	})
}

// PostDelete 删除文章
func (c *AdminController) PostDelete(ctx *gin.Context) {
	idStr := ctx.Param("id")
	if idStr == "" {
		ctx.JSON(http.StatusBadRequest, gin.H{"error": "无效的文章ID"})
		return
	}

	id, err := strconv.Atoi(idStr)
	if err != nil {
		ctx.JSON(http.StatusBadRequest, gin.H{"error": "无效的文章ID"})
		return
	}

	err = c.postService.DeletePost(uint(id))
	if err != nil {
		ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	ctx.Redirect(http.StatusFound, "/admin/posts")
}

// PostEdit 编辑文章
func (c *AdminController) PostEdit(ctx *gin.Context) {
	idStr := ctx.Param("id")
	var id uint
	if idStr != "" && idStr != "new" {
		idInt, err := strconv.Atoi(idStr)
		if err != nil {
			ctx.HTML(http.StatusBadRequest, "error.html", gin.H{
				"title": "无效的ID",
				"error": "无效的文章ID",
			})
			return
		}
		id = uint(idInt)
	}

	// 获取分类列表
	categories, err := c.categoryService.GetCategories()
	if err != nil {
		ctx.HTML(http.StatusInternalServerError, "error.html", gin.H{
			"title": "服务器错误",
			"error": err.Error(),
		})
		return
	}

	// 如果是POST请求，处理表单提交
	if ctx.Request.Method == "POST" {
		title := ctx.PostForm("title")
		content := ctx.PostForm("content")
		categoryIDs := ctx.PostFormArray("categories")
		status := ctx.PostForm("status")
		slug := ctx.PostForm("slug")

		session := sessions.Default(ctx)
		userID, _ := session.Get("user_id").(uint)

		post := &models.Post{
			Content: models.Content{
				Title:    title,
				Text:     content,
				AuthorID: userID,
				Status:   status,
				Slug:     slug,
			},
		}

		// 处理分类
		for _, catIDStr := range categoryIDs {
			catID, _ := strconv.Atoi(catIDStr)
			post.Categories = append(post.Categories, models.Category{ID: uint(catID)})
		}

		if id == 0 {
			// 创建文章
			err = c.postService.CreatePost(post)
		} else {
			// 更新文章
			post.ID = id
			err = c.postService.UpdatePost(post)
		}

		if err != nil {
			ctx.HTML(http.StatusInternalServerError, "error.html", gin.H{
				"title": "服务器错误",
				"error": err.Error(),
			})
			return
		}

		ctx.Redirect(http.StatusFound, "/admin/posts")
		return
	}

	// GET请求，显示编辑页面
	var post models.Post
	if id != 0 {
		post, err = c.postService.GetPostByID(id)
		if err != nil {
			ctx.HTML(http.StatusNotFound, "error.html", gin.H{
				"title": "文章未找到",
				"error": "您要编辑的文章不存在",
			})
			return
		}
	}

	ctx.HTML(http.StatusOK, "admin-post-edit.html", gin.H{
		"title":      "编辑文章",
		"post":       post,
		"categories": categories,
	})
}

// PageList 页面列表
func (c *AdminController) PageList(ctx *gin.Context) {
	// 获取分页参数
	page, _ := strconv.Atoi(ctx.DefaultQuery("page", "1"))
	pageSize, _ := strconv.Atoi(ctx.DefaultQuery("page_size", "10"))

	// 获取页面列表
	pages, total, err := c.pageService.GetPages(page, pageSize)
	if err != nil {
		ctx.HTML(http.StatusInternalServerError, "error.html", gin.H{
			"title": "服务器错误",
			"error": err.Error(),
		})
		return
	}

	ctx.HTML(http.StatusOK, "page-list.html", gin.H{
		"title":      "页面管理",
		"pages":      pages,
		"total":      total,
		"page":       page,
		"pageSize":   pageSize,
		"totalPages": (total + int64(pageSize) - 1) / int64(pageSize),
	})
}

// PageEdit 编辑页面
func (c *AdminController) PageEdit(ctx *gin.Context) {
	id := ctx.Param("id")

	if id == "new" {
		// 新建页面
		ctx.HTML(http.StatusOK, "page-edit.html", gin.H{
			"title": "新建页面",
		})
		return
	}

	// 编辑页面
	idInt, err := strconv.ParseUint(id, 10, 32)
	if err != nil {
		ctx.Redirect(http.StatusFound, "/admin/pages")
		return
	}

	page, err := c.pageService.GetPageByID(uint(idInt))
	if err != nil {
		ctx.Redirect(http.StatusFound, "/admin/pages")
		return
	}

	ctx.HTML(http.StatusOK, "page-edit.html", gin.H{
		"title": "编辑页面",
		"page":  page,
	})
}

// CommentList 评论列表
func (c *AdminController) CommentList(ctx *gin.Context) {
	// 获取分页参数
	page, _ := strconv.Atoi(ctx.DefaultQuery("page", "1"))
	pageSize, _ := strconv.Atoi(ctx.DefaultQuery("page_size", "10"))

	// 获取评论列表
	comments, total, err := c.commentService.GetComments(page, pageSize)
	if err != nil {
		ctx.HTML(http.StatusInternalServerError, "error.html", gin.H{
			"title": "服务器错误",
			"error": err.Error(),
		})
		return
	}

	ctx.HTML(http.StatusOK, "comment-list.html", gin.H{
		"title":      "评论管理",
		"comments":   comments,
		"total":      total,
		"page":       page,
		"pageSize":   pageSize,
		"totalPages": (total + int64(pageSize) - 1) / int64(pageSize),
	})
}

// CategoryList 分类列表
func (c *AdminController) CategoryList(ctx *gin.Context) {
	// 获取分类列表
	categories, err := c.categoryService.GetCategories()
	if err != nil {
		ctx.HTML(http.StatusInternalServerError, "error.html", gin.H{
			"title": "服务器错误",
			"error": err.Error(),
		})
		return
	}

	// 获取分类树
	categoryTree, err := c.categoryService.GetCategoryTree()
	if err != nil {
		ctx.HTML(http.StatusInternalServerError, "error.html", gin.H{
			"title": "服务器错误",
			"error": err.Error(),
		})
		return
	}

	ctx.HTML(http.StatusOK, "category-list.html", gin.H{
		"title":        "分类管理",
		"categories":   categories,
		"categoryTree": categoryTree,
	})
}

// TagList 标签列表
func (c *AdminController) TagList(ctx *gin.Context) {
	// 获取标签列表
	tags, err := c.tagService.GetTags()
	if err != nil {
		ctx.HTML(http.StatusInternalServerError, "error.html", gin.H{
			"title": "服务器错误",
			"error": err.Error(),
		})
		return
	}

	// 获取热门标签
	hotTags, err := c.tagService.GetHotTags(10)
	if err != nil {
		ctx.HTML(http.StatusInternalServerError, "error.html", gin.H{
			"title": "服务器错误",
			"error": err.Error(),
		})
		return
	}

	ctx.HTML(http.StatusOK, "tag-list.html", gin.H{
		"title":   "标签管理",
		"tags":    tags,
		"hotTags": hotTags,
	})
}

// UserList 用户列表
func (c *AdminController) UserList(ctx *gin.Context) {
	// 获取分页参数
	page, _ := strconv.Atoi(ctx.DefaultQuery("page", "1"))
	pageSize, _ := strconv.Atoi(ctx.DefaultQuery("page_size", "10"))

	// 获取用户列表
	users, total, err := c.userService.GetUsers(page, pageSize)
	if err != nil {
		ctx.HTML(http.StatusInternalServerError, "error.html", gin.H{
			"title": "服务器错误",
			"error": err.Error(),
		})
		return
	}

	ctx.HTML(http.StatusOK, "user-list.html", gin.H{
		"title":      "用户管理",
		"users":      users,
		"total":      total,
		"page":       page,
		"pageSize":   pageSize,
		"totalPages": (total + int64(pageSize) - 1) / int64(pageSize),
	})
}

// UserEdit 编辑用户
func (c *AdminController) UserEdit(ctx *gin.Context) {
	id := ctx.Param("id")
	db := database.GetDB()

	if id == "new" {
		// 新建用户
		ctx.HTML(http.StatusOK, "user-edit.html", gin.H{
			"title": "新建用户",
		})
		return
	}

	// 编辑用户
	var user models.User
	result := db.First(&user, id)
	if result.Error != nil {
		ctx.Redirect(http.StatusFound, "/admin/users")
		return
	}

	ctx.HTML(http.StatusOK, "user-edit.html", gin.H{
		"title": "编辑用户",
		"user":  user,
	})
}

// SettingGeneral 常规设置
func (c *AdminController) SettingGeneral(ctx *gin.Context) {
	db := database.GetDB()

	// 获取设置项
	var options []models.Option
	db.Find(&options)

	// 转换为map
	settings := make(map[string]string)
	for _, option := range options {
		settings[option.Name] = option.Value
	}

	ctx.HTML(http.StatusOK, "setting-general.html", gin.H{
		"title":    "常规设置",
		"settings": settings,
	})
}
